package com.ruoyi.system.rabbit;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.ruoyi.common.config.GeoConfig;
import com.ruoyi.common.config.PreventionConfig;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.config.WarnTypeEnum;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.entity.receivevo.ReceiveEnclosureAlert;
import com.ruoyi.system.entity.receivevo.ReceivePersonAlert;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.service.*;
import com.ruoyi.system.service.impl.EnterpriseWXServiceImpl;
import com.ruoyi.system.services.PersonPositionServices;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Component
public class PersonConsumer {

    @Autowired
    private RedisCache redisCache;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Resource
    private KeyAlertService keyAlertService;
    @Resource
    private EnterpriseWXServiceImpl enterpriseWXService;
    @Autowired
    private IEnclosureInfoService enclosureInfoService;
    @Resource
    private EnclosureAlertService enclosureAlertService;
    @Autowired
    private PersonPositionServices personPositionServices;
    @Autowired
    private IPersonCrowdAlertService personCrowdAlertService;
    @Resource
    private KeyPersonnelAdminService keyPersonnelAdminService;
    @Resource
    private JobPlanBillDeclareService jobPlanBillDeclareService;


    /**
     * 上报人员报警数据
     * @return
     */
    private final String receivePersonAlertUrl = "/v1/data/person-position/receiveEmployeeAlarmList";
    /**
     * 上报区域报警数据
     * @return
     */
    private final String receiveEnclosureAlertUrl = "/v1/data/person-position/receiveZoneAlarmList";

    //监听队列
    @RabbitListener(queues = "tenant_msg_52AC4F4F_sc22120928")
    public void listenMessage(String message)
    {
        JSONObject jsonObject = new JSONObject(message);
        log.error("消息队列中，获取到报警消息 ： {}", jsonObject);
        String method = jsonObject.getStr("method");
        if (method.equals("position")) {
            // 人员定位
            cachePersonPosition(jsonObject, message);
        } else if (method.equals("warning")) {
            JSONObject params = jsonObject.getJSONObject("params");
            if (params==null)  { return ; }

            int warnType = 0;
            if (params.containsKey("options") && params.getJSONObject("options").containsKey("warnType")) {
                warnType = params.getJSONObject("options").getInt("warnType");
            }
            if (params.containsKey("type")) {
                warnType = params.getInt("type");
            }

            String triggerName = params.getStr("triggerName");
            if (WarnTypeEnum.WARN_ANJIAN.getName().equals(triggerName)) {
                saveKeyAlert(params);
            } else if (warnType == WarnTypeEnum.WARN_CHUANGANG.getCode()
                        || warnType == WarnTypeEnum.WARN_JINGZHI.getCode()
                        || warnType == WarnTypeEnum.WARN_LIGANG.getCode()
                        || warnType == WarnTypeEnum.WARN_CHAOYUAN.getCode()
                        || warnType == WarnTypeEnum.WARN_QUEYUAN.getCode()) {
                saveEnclosureAlert(params, warnType);
            } else if (warnType == WarnTypeEnum.WARN_JUJI.getCode()) {
                savePersonCrowdAlert(params);
            }
        }
    }

    /**
     * 缓存人员位置信息 (最多6000条)
     */
    public void cachePersonPosition(JSONObject jsonObject, String message) {
        JSONObject params = jsonObject.getJSONObject("params");
        if (!params.containsKey("name")) {
            return;
        }
        String name = params.getStr("name");
        if (StrUtil.isEmpty(name)) {
            return;
        }
        // 人员名称作为key 存入redis
        List<Object> keys = redisCache.getCacheList(name);
        if (keys.size() > 6000) {
            redisCache.redisTemplate.opsForList().trim(name,5000,keys.size() - 1);
        }

        redisCache.setCacheListLeft(name, message);
    }

    /**
     * 保存人员、围栏报警
     */
    public boolean saveEnclosureAlert(JSONObject params, int warnType) {
        EnclosureAlert entity = JSONUtil.toBean(params, EnclosureAlert.class);
        entity.setRaiseTime(DateTime.of(params.getLong("raiseTime")));
        if (params.containsKey("stopTime")) {
            entity.setStopTime(DateTime.of(params.getLong("stopTime")));
        }
        entity.setUserName(params.getStr("name"));

        enclosureAlertService.insert(entity);
        // 围栏上报：超员报警-1, 缺员报警-2，缺岗报警-3
        if (warnType == WarnTypeEnum.WARN_CHAOYUAN.getCode()) {
            pushEnclosureWarn(entity, "1");
        }
        if (warnType == WarnTypeEnum.WARN_QUEYUAN.getCode()) {
            pushEnclosureWarn(entity, "2");
        }
        if (warnType == WarnTypeEnum.WARN_LIGANG.getCode()) {
            pushEnclosureWarn(entity, "3");
        }

        // sos报警-0，越界报警-1，滞留报警-2，静止报警-3，离场报警-4
        if (warnType == WarnTypeEnum.WARN_CHUANGANG.getCode()) {
            pushPersonWarn(entity, "1");
        }
        if (warnType == WarnTypeEnum.WARN_JINGZHI.getCode()) {
            pushPersonWarn(entity, "3");
        }

        return true;
    }

    /**
     * 保存人员聚集报警
     */
    public boolean savePersonCrowdAlert(JSONObject params) {
        PersonCrowdAlert entity = JSONUtil.toBean(params, PersonCrowdAlert.class);
        JSONObject options = params.getJSONObject("options");
        if (options!=null) {
            entity.setTriggerName(options.getStr("triggerName"));
            entity.setGatherDistance(options.getStr("gatherDistance"));
            entity.setEnclosureId(options.getInt("enclosureId"));
            entity.setPoint(options.getJSONObject("point").toString());
        }
        entity.setRaiseTime(DateTime.of(params.getLong("raiseTime")));
        entity.setStopTime(DateTime.of(params.getLong("stopTime")));

        personCrowdAlertService.insertPersonCrowdAlert(entity);
        return true;
    }

    /**
     * 推送人员报警数据 到市局
     *
     * sos报警-0，越界报警-1，滞留报警-2，静止报警-3，离场报警-4
     */
    public boolean pushPersonWarn(EnclosureAlert entity, String alarmType) {
        // 市局上报围栏ID
        ReceivePersonAlert vo = ReceivePersonAlert.enclosureAlertToReceivePersonAlert(entity);
        vo.setAlarmType(alarmType);
        EnclosureInfo enclosure = enclosureInfoService.selectEnclosureBySynId(entity.getEnclosureId());
        if (enclosure==null) {
            return false;
        }
        vo.setZoneId(enclosure.getGovernId());

        // 市局上报人员ID
        KeyPersonnelAdmin keyPersonnelAdmin = keyPersonnelAdminService.selectByPositionUserId(entity.getEntityId());
        if (keyPersonnelAdmin==null) {
            return false;
        }
        vo.setPersonId(keyPersonnelAdmin.getGovernId());

        // 人员位置
        String positionObj = personPositionServices.getPersonPosition(entity.getTagId(), entity.getRaiseTime().getTime());
        if (StringUtils.isEmpty(positionObj)) {
            return false;
        }
        JSONObject positionJson = JSONUtil.parseObj(positionObj);
        Long longitude = positionJson.getJSONObject("data").getLong("longitude");
        Long latitude = positionJson.getJSONObject("data").getLong("latitude");
        if (longitude==null || latitude==null) {
            return false;
        }
        vo.setLongitude(String.format("%.6f", longitude));
        vo.setLatitude(String.format("%.6f", latitude));

        List<ReceivePersonAlert> list = new ArrayList<>();
        list.add(vo);
        // 人员报警
        String pushResult = PreventionConfig.pushData(JSONUtil.toJsonPrettyStr(list), receivePersonAlertUrl);
        entity.setGovernId(vo.getId());
        entity.setIsUpload(1);
        enclosureAlertService.update(entity);

        return true;
    }

    /**
     * 推送区域报警数据 到市局
     * 超员报警-1, 缺员报警-2，缺岗报警-3
     */
    public void pushEnclosureWarn(EnclosureAlert entity, String alarmType) {
        ReceiveEnclosureAlert vo = ReceiveEnclosureAlert.enclosureAlertToReceiveEnclosureAlert(entity);
        vo.setAlarmType(alarmType);
        EnclosureInfo enclosure = enclosureInfoService.selectEnclosureBySynId(entity.getEnclosureId());
        vo.setZoneId(enclosure.getGovernId());

        List<ReceiveEnclosureAlert> list = new ArrayList<>();
        list.add(vo);
        // 市局推送围栏报警数据
        String s = PreventionConfig.pushData(JSONUtil.toJsonPrettyStr(list), receiveEnclosureAlertUrl);
        entity.setGovernId(vo.getId());
        entity.setIsUpload(1);
        enclosureAlertService.update(entity);
    }


    /**
     * 保存按键报警 (等于sos)
     */
    public boolean saveKeyAlert(JSONObject params) {
        KeyAlert keyAlert = JSONUtil.toBean(params, KeyAlert.class);
        keyAlert.setRaiseTime(DateTime.of(params.getLong("raiseTime")));
        keyAlert.setStopTime(DateTime.of(params.getLong("stopTime")));
        // 入库
        keyAlertService.insert(keyAlert);

        // 推送市局
        return pushPersonSOSWarn(keyAlert);
    }

    /**
     * 推送人员报警-sos报警 到市局
     */
    public boolean pushPersonSOSWarn(KeyAlert keyAlert) {
        ReceivePersonAlert vo = ReceivePersonAlert.keyAlertToReceivePersonAlert(keyAlert);
        vo.setAlarmType("0");

        // 查询上报市局的人员信息
        Integer entityId = keyAlert.getEntityId();
        if (entityId==null) {
            return false;
        }
        KeyPersonnelAdmin keyPersonnelAdmin = keyPersonnelAdminService.selectByPositionUserId(entityId);
        if (keyPersonnelAdmin==null) {
            return false;
        }
        vo.setPersonId(keyPersonnelAdmin.getGovernId());

        // 市局推送人员定位数据
        List<ReceivePersonAlert> list = new ArrayList<>();
        list.add(vo);
        String result = PreventionConfig.pushData(JSONUtil.toJsonPrettyStr(list), receivePersonAlertUrl);
        keyAlert.setUserName(keyPersonnelAdmin.getName());
        keyAlert.setGovernId(vo.getId());
        keyAlert.setIsUpload(1);
        keyAlertService.update(keyAlert);

        return true;
    }



    public void sendWxMsg(JobPlanEnclosureWarn enclosureWarn) {
        if (enclosureWarn.getEnclosureId()==null && enclosureWarn.getTriggerId()==null) {
            return;
        }

        JobPlanBillDeclare JobPlanBillDeclare = new JobPlanBillDeclare();
        JobPlanBillDeclare.setEnclosureId(enclosureWarn.getEnclosureId().intValue());
        JobPlanBillDeclare.setRuleId(enclosureWarn.getTriggerId());
        JobPlanBillDeclare jobPlanBillDeclare = jobPlanBillDeclareService.selectByEnclosureId(JobPlanBillDeclare);
        String jobPersonChargeId = jobPlanBillDeclare.getJobPersonChargeId();
        if (StringUtils.isEmpty(jobPersonChargeId))  { return ; }

        Integer userWxId = sysUserMapper.selectUserWXIdById(Integer.parseInt(jobPersonChargeId));
        if (userWxId==null)  { return ; }
        String message = "作业计划：" + JobPlanBillDeclare.getBillNumber() + ", 围栏区域内出现超员报警，请关注！";
        enterpriseWXService.sendMessageToWx(message, userWxId +"");
    }
}
